package org.chen.flight.service.flight;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.chen.common.flight.*;
import org.chen.common.flight.request.FlightSearchRequest;
import org.chen.common.flight.response.RoundTripFlightSearchResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class RoundTripFlightParseService {

    @Autowired
    private FlightMetadataService metadataService;

    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 解析往返机票响应数据
     */
    public RoundTripFlightSearchResponse parseRoundTripResponse(Map<String, Object> responseBody,
                                                                FlightSearchData searchData,
                                                                FlightSearchRequest request) {
        RoundTripFlightSearchResponse response = RoundTripFlightSearchResponse.success();
        response.setSearchRequest(request);
        response.setTransactionId(searchData.getTransactionID());

        try {
            Integer status = (Integer) responseBody.get("status");
            String msg = (String) responseBody.get("msg");

            if (status == null || status != 0 || !"success".equals(msg)) {
                response.setSuccess(false);
                response.setMessage("API返回错误: " + msg);
                return response;
            }

            Map<String, Object> data = (Map<String, Object>) responseBody.get("data");
            if (data != null) {
                List<RoundTripFlightInfo> flights = parseRoundTripFlights(data);
                response.setFlights(flights);
                response.setTotalCount(flights.size());
                response.setMetadata(extractMetadata(data, request));
            }

        } catch (Exception e) {
            log.error("解析往返机票响应数据失败", e);
            response.setSuccess(false);
            response.setMessage("解析响应数据失败: " + e.getMessage());
        }

        return response;
    }

    /**
     * 解析往返航班列表
     */
    private List<RoundTripFlightInfo> parseRoundTripFlights(Map<String, Object> data) {
        List<RoundTripFlightInfo> flights = new ArrayList<>();
        List<Map<String, Object>> flightItineraryList = (List<Map<String, Object>>) data.get("flightItineraryList");

        if (flightItineraryList != null && !flightItineraryList.isEmpty()) {
            for (int i = 0; i < flightItineraryList.size(); i++) {
                Map<String, Object> itinerary = flightItineraryList.get(i);
                try {
                    List<RoundTripFlightInfo> itineraryFlights = parseRoundTripItinerary(itinerary);
                    flights.addAll(itineraryFlights);
                } catch (Exception e) {
                    log.warn("解析第 {} 个往返航班行程失败: {}", i + 1, e.getMessage());
                }
            }
        }

        return flights;
    }

    /**
     * 解析往返行程
     */
    private List<RoundTripFlightInfo> parseRoundTripItinerary(Map<String, Object> itinerary) {
        List<RoundTripFlightInfo> flights = new ArrayList<>();
        String itineraryId = getStringValue(itinerary, "itineraryId");

        List<Map<String, Object>> priceList = (List<Map<String, Object>>) itinerary.get("priceList");
        List<Map<String, Object>> flightSegments = (List<Map<String, Object>>) itinerary.get("flightSegments");

        if (priceList != null && flightSegments != null) {
            for (int i = 0; i < priceList.size(); i++) {
                Map<String, Object> priceInfo = priceList.get(i);
                RoundTripFlightInfo flight = parseRoundTripFlight(itineraryId, i, priceInfo, flightSegments);
                if (flight != null) {
                    flights.add(flight);
                }
            }
        }

        return flights;
    }

    /**
     * 解析单个往返航班
     */
    private RoundTripFlightInfo parseRoundTripFlight(String itineraryId, int priceIndex,
                                                     Map<String, Object> priceInfo,
                                                     List<Map<String, Object>> flightSegments) {
        try {
            RoundTripFlightInfo flight = new RoundTripFlightInfo();
            flight.setItineraryId(itineraryId);
            flight.setPriceIndex(priceIndex);

            Map<String, Object> firstSegment = flightSegments.get(0);

            // 基础信息
            Integer transferCount = getIntValue(firstSegment, "transferCount");
            Integer crossDays = getIntValue(firstSegment, "crossDays");
            flight.setTransferCount(transferCount);
            flight.setCrossDays(crossDays);

            // 解析价格信息
            parseRoundTripPriceInfo(flight, priceInfo);

            // 解析去程和返程信息
            parseOutboundAndReturnFlights(flight, priceInfo);

            // 计算总体特征
            calculateRoundTripFeatures(flight);

            return flight;

        } catch (Exception e) {
            log.warn("解析往返航班失败: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 解析往返价格信息
     */
    private void parseRoundTripPriceInfo(RoundTripFlightInfo flight, Map<String, Object> priceInfo) {
        // 成人价格
        Integer adultPrice = (Integer) priceInfo.get("adultPrice");
        Integer adultTax = (Integer) priceInfo.get("adultTax");
        if (adultPrice != null && adultTax != null) {
            flight.setAdultTotalPrice(BigDecimal.valueOf(adultPrice + adultTax));
            flight.setAdultPrice(BigDecimal.valueOf(adultPrice));
            flight.setAdultTax(BigDecimal.valueOf(adultTax));
        }

        // 儿童价格
        Integer childPrice = (Integer) priceInfo.get("childPrice");
        Integer childTax = (Integer) priceInfo.get("childTax");
        if (childPrice != null && childTax != null) {
            flight.setChildTotalPrice(BigDecimal.valueOf(childPrice + childTax));
            flight.setChildPrice(BigDecimal.valueOf(childPrice));
            flight.setChildTax(BigDecimal.valueOf(childTax));
        }

        // 婴儿价格
        Integer infantPrice = (Integer) priceInfo.get("infantPrice");
        Integer infantTax = (Integer) priceInfo.get("infantTax");
        if (infantPrice != null && infantTax != null) {
            flight.setInfantTotalPrice(BigDecimal.valueOf(infantPrice + infantTax));
            flight.setInfantPrice(BigDecimal.valueOf(infantPrice));
            flight.setInfantTax(BigDecimal.valueOf(infantTax));
        }

        flight.setCurrency("CNY");
        flight.setCabinClass(getStringValue(priceInfo, "cabin"));
        flight.setMiseryIndex((Integer) priceInfo.get("miseryIndex"));
        flight.setTicketCount((Integer) priceInfo.get("ticketCount"));

        // 解析行李信息
        parseBaggageInfo(flight, (Map<String, Object>) priceInfo.get("baggage"));

        // 解析购买须知
        List<String> purchaseNotes = (List<String>) priceInfo.get("purchaseNotes");
        flight.setPurchaseNotes(purchaseNotes);
    }

    /**
     * 解析去程和返程航班信息
     */
    private void parseOutboundAndReturnFlights(RoundTripFlightInfo flight, 
                                               Map<String, Object> priceInfo) {
        String luggageVisaKey = getStringValue(priceInfo, "luggageVisaKey");
        if (luggageVisaKey == null || luggageVisaKey.isEmpty()) {
            log.warn("往返航班缺少详细信息");
            return;
        }

        try {
            Map<String, Object> visaData = objectMapper.readValue(luggageVisaKey, Map.class);
            Map<String, Object> criteria = (Map<String, Object>) visaData.get("criteria");

            if (criteria != null) {
                List<Map<String, Object>> flightInfoList = (List<Map<String, Object>>) criteria.get("FlightInfoList");

                if (flightInfoList != null && !flightInfoList.isEmpty()) {
                    // 分离去程和返程航段
                    List<FlightSegmentDetail> outboundSegments = new ArrayList<>();
                    List<FlightSegmentDetail> returnSegments = new ArrayList<>();

                    for (Map<String, Object> flightInfo : flightInfoList) {
                        FlightSegmentDetail segment = parseFlightSegmentDetail(flightInfo);
                        int segmentNo = getIntValue(flightInfo, "SegmentNo");
                        
                        if (segmentNo == 1) {
                            outboundSegments.add(segment);
                        } else if (segmentNo == 2) {
                            returnSegments.add(segment);
                        }
                    }

                    // 按SequenceNo排序
                    outboundSegments.sort(Comparator.comparing(FlightSegmentDetail::getSequenceNo));
                    returnSegments.sort(Comparator.comparing(FlightSegmentDetail::getSequenceNo));

                    // 创建去程航班信息
                    OneWayFlightInfo outboundFlight = createOneWayFromSegments(outboundSegments, flight);
                    flight.setOutboundFlight(outboundFlight);

                    // 创建返程航班信息
                    OneWayFlightInfo returnFlight = createOneWayFromSegments(returnSegments, flight);
                    flight.setReturnFlight(returnFlight);
                }
            }

        } catch (Exception e) {
            log.warn("解析往返航班详细信息失败: {}", e.getMessage());
        }
    }

    /**
     * 从航段信息创建单程航班信息
     */
    private OneWayFlightInfo createOneWayFromSegments(List<FlightSegmentDetail> segments, 
                                                      RoundTripFlightInfo parentFlight) {
        if (segments == null || segments.isEmpty()) {
            return null;
        }

        OneWayFlightInfo oneWay = new OneWayFlightInfo();
        
        // 继承基础信息
        oneWay.setItineraryId(parentFlight.getItineraryId());
        oneWay.setPriceIndex(parentFlight.getPriceIndex());
        oneWay.setCurrency(parentFlight.getCurrency());
        oneWay.setCabinClass(parentFlight.getCabinClass());
        oneWay.setBaggageInfo(parentFlight.getBaggageInfo());
        oneWay.setPurchaseNotes(parentFlight.getPurchaseNotes());

        oneWay.setMiseryIndex(parentFlight.getMiseryIndex());

        // 成人价格
        oneWay.setAdultTotalPrice(parentFlight.getAdultTotalPrice());
        oneWay.setAdultPrice(parentFlight.getAdultPrice());
        oneWay.setAdultTax(parentFlight.getAdultTax());

        // 儿童价格
        oneWay.setChildTotalPrice(parentFlight.getChildTotalPrice());
        oneWay.setChildPrice(parentFlight.getChildPrice());
        oneWay.setChildTax(parentFlight.getChildTax());

        // 婴儿价格
        oneWay.setInfantTotalPrice(parentFlight.getInfantTotalPrice());
        oneWay.setInfantPrice(parentFlight.getInfantPrice());
        oneWay.setInfantTax(parentFlight.getInfantTax());

        // 设置航段信息
        oneWay.setSegments(segments);

        // 生成航班号
        String flightNumber = segments.stream()
                .map(f -> getAirlineName(f.getAirlineCode()) + " " + f.getFlightNo())
                .collect(Collectors.joining(" + "));
        oneWay.setFlightNumber(flightNumber);

        // 设置出发和到达信息
        FlightSegmentDetail firstSegment = segments.get(0);
        FlightSegmentDetail lastSegment = segments.get(segments.size() - 1);

        oneWay.setDepartureTime(firstSegment.getDepartureDateTime());
        oneWay.setDepartureAirportCode(firstSegment.getDepartureAirportCode());
        oneWay.setDepartureCityCode(firstSegment.getDepartureCityCode());
        oneWay.setDepartureTerminal(firstSegment.getDepartureTerminal());

        oneWay.setArrivalTime(lastSegment.getArrivalDateTime());
        oneWay.setArrivalAirportCode(lastSegment.getArrivalAirportCode());
        oneWay.setArrivalCityCode(lastSegment.getArrivalCityCode());
        oneWay.setArrivalTerminal(lastSegment.getArrivalTerminal());

        oneWay.setAirlineCode(firstSegment.getAirlineCode());

        // 设置中转信息
        int transferCount = Math.max(0, segments.size() - 1);
        oneWay.setTransferCount(transferCount);
        oneWay.setIsDirectFlight(transferCount == 0);

        // 计算飞行时长
        calculateTotalDuration(oneWay, segments);

        // 计算中转等待时间
        if (transferCount > 0) {
            calculateTransferWaitTimes(oneWay, segments);
        }

        // 增强元数据
        metadataService.enhanceOneWayFlightInfo(oneWay);

        return oneWay;
    }

    /**
     * 获取航空公司名称
     */
    public String getAirlineName(String airlineCode) {
        Map<String, String> airlineNames = new HashMap<>();
        airlineNames.put("MU", "东方航空");
        airlineNames.put("CA", "国航");
        airlineNames.put("CZ", "南方航空");
        airlineNames.put("HU", "海南航空");
        airlineNames.put("3U", "四川航空");
        airlineNames.put("9C", "春秋航空");
        airlineNames.put("TK", "土耳其航空");
        airlineNames.put("QR", "卡塔尔航空");
        airlineNames.put("EK", "阿联酋航空");
        airlineNames.put("SQ", "新加坡航空");
        airlineNames.put("TG", "泰国航空");

        airlineNames.put("SL", "泰国狮子航空");
        airlineNames.put("VZ", "越捷泰国航空");
        airlineNames.put("FD", "亚洲航空泰国分公司");
        airlineNames.put("ZH", "深圳航空");
        airlineNames.put("MF", "厦门航空");
        airlineNames.put("NX", "澳门航空");
        airlineNames.put("OD", "马印航空");
        airlineNames.put("CX", "国泰航空");

        return airlineNames.getOrDefault(airlineCode, airlineCode);
    }

    /**
     * 计算往返航班总体特征
     */
    private void calculateRoundTripFeatures(RoundTripFlightInfo flight) {
        OneWayFlightInfo outbound = flight.getOutboundFlight();
        OneWayFlightInfo returnFlight = flight.getReturnFlight();

        if (outbound != null && returnFlight != null) {
            // 计算总中转次数
            int totalTransfers = outbound.getTransferCount() + returnFlight.getTransferCount();
            flight.setTotalTransferCount(totalTransfers);

            // 判断是否都是直飞
            boolean allDirectFlight = outbound.getIsDirectFlight() && returnFlight.getIsDirectFlight();
            flight.setIsAllDirectFlight(allDirectFlight);

            // 设置行李信息（使用去程的行李信息）
            if (flight.getBaggageInfo() == null) {
                flight.setBaggageInfo(outbound.getBaggageInfo());
            }
        }
    }

    /**
     * 计算总飞行时长
     */
    private void calculateTotalDuration(OneWayFlightInfo flight, List<FlightSegmentDetail> segments) {
        try {
            LocalDateTime firstDeparture = segments.get(0).getDepartureDateTime();
            LocalDateTime lastArrival = segments.get(segments.size() - 1).getArrivalDateTime();

            long totalMinutes = Duration.between(firstDeparture, lastArrival).toMinutes();

            if (totalMinutes < 60) {
                flight.setDuration(totalMinutes + "分钟");
            } else {
                long hours = totalMinutes / 60;
                long minutes = totalMinutes % 60;
                flight.setDuration(String.format("%d小时%d分钟", hours, minutes));
            }
        } catch (Exception e) {
            log.warn("计算总飞行时长失败: {}", e.getMessage());
            flight.setDuration("未知");
        }
    }

    /**
     * 计算中转等待时间
     */
    private void calculateTransferWaitTimes(OneWayFlightInfo flight, List<FlightSegmentDetail> segments) {
        List<String> waitTimes = new ArrayList<>();
        
        for (int i = 0; i < segments.size() - 1; i++) {
            FlightSegmentDetail currentSegment = segments.get(i);
            FlightSegmentDetail nextSegment = segments.get(i + 1);

            String waitTime = calculateWaitTime(
                    currentSegment.getArrivalDateTime(),
                    nextSegment.getDepartureDateTime()
            );
            waitTimes.add(waitTime);
        }

        flight.setTransferWaitTimes(waitTimes);
    }

    /**
     * 计算等待时间
     */
    private String calculateWaitTime(LocalDateTime arrivalTime, LocalDateTime departureTime) {
        try {

            long minutes = Duration.between(arrivalTime, departureTime).toMinutes();

            if (minutes < 60) {
                return minutes + "分钟";
            } else {
                long hours = minutes / 60;
                long remainingMinutes = minutes % 60;
                return remainingMinutes > 0 ?
                        String.format("%d小时%d分钟", hours, remainingMinutes) :
                        String.format("%d小时", hours);
            }
        } catch (Exception e) {
            log.warn("计算等待时间失败: {}", e.getMessage());
            return "未知";
        }
    }

    /**
     * 解析航段详细信息
     */
    private FlightSegmentDetail parseFlightSegmentDetail(Map<String, Object> flightInfo) {
        FlightSegmentDetail segment = new FlightSegmentDetail();

        segment.setSegmentNo(getIntValue(flightInfo, "SegmentNo"));
        segment.setSequenceNo(getIntValue(flightInfo, "SequenceNo"));
        segment.setFlightNo(getStringValue(flightInfo, "MarketingFlightNo"));
        segment.setAirlineCode(getStringValue(flightInfo, "MarketingCarrierCode"));
        segment.setSeatClass(getStringValue(flightInfo, "SeatClass"));
        segment.setCabin(getStringValue(flightInfo, "Cabin"));

        segment.setDepartureAirportCode(getStringValue(flightInfo, "DepartureAirportCode"));
        segment.setDepartureCityCode(getStringValue(flightInfo, "DepartureCityCode"));
        segment.setDepartureTerminal(getStringValue(flightInfo, "DepartureTerminal"));

        segment.setArrivalAirportCode(getStringValue(flightInfo, "ArrivalAirportCode"));
        segment.setArrivalCityCode(getStringValue(flightInfo, "ArrivalCityCode"));
        segment.setArrivalTerminal(getStringValue(flightInfo, "ArrivalTerminal"));

        segment.setTimesFromString(getStringValue(flightInfo, "TakeOffDateTime"), getStringValue(flightInfo, "ArrivalDateTime"));

        segment.setIsTransit(getBooleanValue(flightInfo, "IsTransit"));

        return segment;
    }

    /**
     * 解析行李信息
     */
    private void parseBaggageInfo(RoundTripFlightInfo flight, Map<String, Object> baggage) {
        if (baggage == null) return;

        List<Map<String, Object>> dataList = (List<Map<String, Object>>) baggage.get("dataList");
        if (dataList != null && !dataList.isEmpty()) {
            Map<String, Object> firstBaggage = dataList.get(0);
            Map<String, Object> adultBaggage = (Map<String, Object>) firstBaggage.get("adultBaggage");

            if (adultBaggage != null) {
                Map<String, Object> checkedBaggage = (Map<String, Object>) adultBaggage.get("checkedBaggage");
                if (checkedBaggage != null) {
                    flight.setBaggageInfo(getStringValue(checkedBaggage, "baggageContent"));
                }
            }
        }
    }

    /**
     * 提取元数据
     */
    private Map<String, Object> extractMetadata(Map<String, Object> data, FlightSearchRequest request) {
        Map<String, Object> metadata = new HashMap<>();
        metadata.put("searchTime", LocalDateTime.now().toString());
        metadata.put("tripType", "roundtrip");

        Map<String, Object> context = (Map<String, Object>) data.get("context");
        if (context != null) {
            metadata.put("searchId", context.get("searchId"));
            metadata.put("finished", context.get("finished"));
            metadata.put("existDirectReturnTrip", context.get("existDirectReturnTrip"));
        }

        List<Map<String, Object>> flightItineraryList = (List<Map<String, Object>>) data.get("flightItineraryList");
        if (flightItineraryList != null) {
            metadata.put("itineraryCount", flightItineraryList.size());
        }

        return metadata;
    }

    // 辅助方法
    private String getStringValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        return value != null ? value.toString() : null;
    }

    private int getIntValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value instanceof Number) {
            return ((Number) value).intValue();
        }
        return 0;
    }

    private boolean getBooleanValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        return value instanceof Boolean ? (Boolean) value : false;
    }
}